home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 3: CDPD 3
/
Almathera Ten on Ten - Disc 3: CDPD3.iso
/
fish
/
676-700
/
681
/
term
/
source.lha
/
termXPR.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-09
|
46KB
|
2,060 lines
/*
** $Id: termXPR.c,v 1.7 92/05/01 12:51:43 olsen Sta Locker: olsen $
** $Revision: 1.7 $
** $Date: 92/05/01 12:51:43 $
**
** External transfer protocol support routines
**
** Copyright © 1990-1992 by Olaf `Olsen' Barthel & MXM
** All Rights Reserved
*/
#include "termGlobal.h"
/* How many options will xpr_options display in a single column. */
#define OPTION_WRAP 16
/* These variables keep the transferred bytes and transfer
* time in seconds.
*/
STATIC LONG ByteVal,ByteMax,TimeVal,TimeMax;
/* The name of the file being transmitted, in case the
* `override transfer path' feature is enabled.
*/
STATIC UBYTE RealName[256];
STATIC struct Buffer *CurrentFile;
/* Yet another flag, this one determines whether we already told
* the user that the file we are currently processing will fit
* on the destination device.
*/
STATIC BYTE Alerted;
/* xpr_fopen(UBYTE *FileName,UBYTE *AccessMode):
*
* Open a file for random access.
*/
LONG __saveds __asm
xpr_fopen(register __a0 UBYTE *FileName,register __a1 UBYTE *AccessMode)
{
struct Buffer *File;
Alerted = FALSE;
/* Reset transfer counters. */
ByteVal = ByteMax = TimeVal = TimeMax = 0;
/* Disable the time and data bars in the transfer window. */
if(TransferWindow)
{
GhostStats(TransferGadgetArray[2]);
GhostStats(TransferGadgetArray[3]);
}
/* Remember file name. */
strcpy(RealName,FileName);
/* Build a new filename if neccessary. */
if(Config . OverridePath)
{
if(!Uploading)
{
if(!DownloadPath)
{
if(!Config . BinaryDownloadPath[0])
{
if(!GetCurrentDirName(RealName,256))
RealName[0] = 0;
}
else
strcpy(RealName,Config . BinaryDownloadPath);
}
else
{
if(!DownloadPath[0])
{
if(!GetCurrentDirName(RealName,256))
RealName[0] = 0;
}
else
strcpy(RealName,DownloadPath);
}
if(AddPart(RealName,FilePart(FileName),256))
FileName = RealName;
else
strcpy(RealName,FileName);
}
}
/* Determine file transfer mode... */
if(File = BufferOpen(FileName,AccessMode))
{
switch(AccessMode[0])
{
case 'r': LogAction(LocaleString(MSG_TERMXPR_LOGMSG_SEND_FILE_TXT),FileName);
break;
case 'w': LogAction(LocaleString(MSG_TERMXPR_LOGMSG_RECEIVE_FILE_TXT),FileName);
AddDownloadObject(FileName);
break;
case 'a': LogAction(LocaleString(MSG_TERMXPR_LOGMSG_UPDATE_FILE_TXT),FileName);
break;
}
CurrentFile = File;
}
DidTransfer = TRUE;
return((LONG)File);
}
/* xpr_fclose(struct Buffer *File):
*
* Close a file opened by xpr_fopen.
*/
LONG __saveds __asm
xpr_fclose(register __a0 struct Buffer *File)
{
BYTE WriteAccess = File -> WriteAccess;
/* Close the file and see what it brings... */
if(BufferClose(File))
{
/* Did we receive or send a file? */
if(WriteAccess)
{
LONG Size;
/* Did the file remain empty? */
if(!(Size = GetFileSize(RealName)))
{
AddTransferInfo(LocaleString(MSG_TERMXPR_FILE_REMOVED_TXT),FilePart(RealName));
/* Delete empty file. */
if(DeleteFile(RealName))
LogAction(LocaleString(MSG_TERMXPR_CLOSE_FILE_REMOVED_TXT),RealName);
else
LogAction(LocaleString(MSG_TERMXPR_CLOSE_FILE_TXT),RealName);
}
else
{
if(ByteMax)
{
if(Size == ByteMax)
AddTransferInfo(LocaleString(MSG_TERMXPR_FILE_RECEIVED_TXT),FilePart(RealName));
else
AddTransferInfo(LocaleString(MSG_TERMXPR_INCOMPLETE_FILE_RECEIVED_TXT),FilePart(RealName));
}
/* Try to identify the file type. */
Identify(RealName);
LogAction(LocaleString(MSG_TERMXPR_CLOSE_FILE_BYTES_TXT),RealName,Size);
}
}
else
{
/* Set the archived bit on files we uploaded? */
if(Config . SetArchivedBit)
{
BPTR FileLock;
/* Get a lock on it. */
if(FileLock = Lock(RealName,ACCESS_READ))
{
struct FileInfoBlock __aligned FileInfo;
/* Examine the file. */
if(Examine(FileLock,&FileInfo))
{
/* Remove the lock. */
UnLock(FileLock);
/* Set the `archived' bit. */
SetProtection(RealName,FileInfo . fib_Protection | FIBF_ARCHIVE);
}
else
UnLock(FileLock);
}
}
AddTransferInfo(LocaleString(MSG_TERMXPR_FILE_SENT_TXT),FilePart(RealName));
LogAction(LocaleString(MSG_TERMXPR_CLOSE_FILE_TXT),RealName);
}
}
RealName[0] = 0;
CurrentFile = NULL;
return(1);
}
/* xpr_fread(APTR Buffer,LONG Size,LONG Count,struct Buffer *File):
*
* Read a few bytes from a file.
*/
LONG __saveds __asm
xpr_fread(register __a0 APTR Buffer,register __d0 LONG Size,register __d1 LONG Count,register __a1 struct Buffer *File)
{
return(BufferRead(File,Buffer,Size * Count) / Size);
}
/* xpr_fwrite(APTR Buffer,LONG Size,LONG Count,struct Buffer *File):
*
* Write a few bytes to a file.
*/
LONG __saveds __asm
xpr_fwrite(register __a0 APTR Buffer,register __d0 LONG Size,register __d1 LONG Count,register __a1 struct Buffer *File)
{
return(BufferWrite(File,Buffer,Size * Count) / Size);
}
/* xpr_fseek(struct Buffer *File,LONG Offset,LONG Origin):
*
* Move the read/write pointer in a file.
*/
LONG __saveds __asm
xpr_fseek(register __a0 struct Buffer *File,register __d0 LONG Offset,register __d1 LONG Origin)
{
return(BufferSeek(File,Offset,Origin) ? 0 : -1);
}
/* xpr_sread(UBYTE *Buffer,LONG Size,LONG Timeout):
*
* Read a few bytes from the serial port (including
* timeouts).
*/
ULONG __saveds __asm
xpr_sread(register __a0 UBYTE *Buffer,register __d0 ULONG Size,register __d1 LONG Timeout)
{
/* Valid parameters? */
if(WriteRequest && Size)
{
/* How many bytes are still in the serial buffer? */
WriteRequest -> IOSer . io_Command = SDCMD_QUERY;
DoIO(WriteRequest);
/* No timeout specified? Return as many bytes
* as are currently within the buffer.
*/
if(Timeout < 1)
{
/* Are there any bytes in the buffer? */
if(WriteRequest -> IOSer . io_Actual > 0)
{
/* More bytes available than requested? */
if(Size < WriteRequest -> IOSer . io_Actual)
ReadRequest -> IOSer . io_Length = Size;
else
ReadRequest -> IOSer . io_Length = WriteRequest -> IOSer . io_Actual;
/* Fill the buffer. */
ReadRequest -> IOSer . io_Command = CMD_READ;
ReadRequest -> IOSer . io_Data = Buffer;
if(!DoIO(ReadRequest))
return(ReadRequest -> IOSer . io_Actual);
}
}
else
{
if(WriteRequest -> IOSer . io_Actual < Size)
{
register ULONG SignalSet;
/* Set up the timer. */
TimeRequest -> tr_node . io_Command = TR_ADDREQUEST;
TimeRequest -> tr_time . tv_secs = Timeout >= MILLION ? Timeout / MILLION : 0;
TimeRequest -> tr_time . tv_micro = Timeout % MILLION;
/* Set up the read request. */
ReadRequest -> IOSer . io_Command = CMD_READ;
ReadRequest -> IOSer . io_Data = Buffer;
ReadRequest -> IOSer . io_Length = Size;
/* Prevent early termination. */
SetSignal(0,SIG_SERIAL | SIG_TIMER);
/* Start IO... */
SendIO(ReadRequest);
SendIO(TimeRequest);
FOREVER
{
/* Build signal mask. */
if(TransferWindow)
SignalSet = SIG_SERIAL | SIG_TIMER | (1 << TransferWindow -> UserPort -> mp_SigBit);
else
SignalSet = SIG_SERIAL | SIG_TIMER;
/* Wait for either of both IORequests to return. */
SignalSet = Wait(SignalSet);
/* Hit by timeout? */
if(SignalSet & SIG_TIMER)
{
/* Abort the read request. */
AbortIO(ReadRequest);
WaitIO(ReadRequest);
/* Remove the timer request. */
WaitIO(TimeRequest);
/* Did the driver receive any
* data?
*/
if(!ReadRequest -> IOSer . io_Actual)
{
/* Take a second look and query the number of
* bytes ready to be received, there may
* still be some bytes in the buffer.
* Note: this depends on the way the
* driver handles read abort.
*/
WriteRequest -> IOSer . io_Command = SDCMD_QUERY;
DoIO(WriteRequest);
/* Are there any bytes to transfer? */
if(WriteRequest -> IOSer . io_Actual > 0)
{
/* Don't read more than actually wanted. */
if(Size < WriteRequest -> IOSer . io_Actual)
ReadRequest -> IOSer . io_Length = Size;
else
ReadRequest -> IOSer . io_Length = WriteRequest -> IOSer . io_Actual;
ReadRequest -> IOSer . io_Command = CMD_READ;
ReadRequest -> IOSer . io_Data = Buffer;
/* Read the data. */
if(!DoIO(ReadRequest))
return(ReadRequest -> IOSer . io_Actual);
else
return(0);
}
else
return(0);
}
else
return(ReadRequest -> IOSer . io_Actual);
}
/* Receive buffer filled? */
if(SignalSet & SIG_SERIAL)
{
AbortIO(TimeRequest);
WaitIO(TimeRequest);
WaitIO(ReadRequest);
if(!ReadRequest -> IOSer . io_Error)
return(ReadRequest -> IOSer . io_Actual);
else
return(0);
}
/* Check the transfer window for
* possible user abort.
*/
if(TransferWindow)
{
if(SignalSet & (1 << TransferWindow -> UserPort -> mp_SigBit))
{
if(xpr_chkabort() == -1)
{
AbortIO(ReadRequest);
AbortIO(TimeRequest);
WaitIO(ReadRequest);
WaitIO(TimeRequest);
SendAbort = TRUE;
return(-1);
}
}
}
}
}
else
{
ReadRequest -> IOSer . io_Command = CMD_READ;
ReadRequest -> IOSer . io_Data = Buffer;
ReadRequest -> IOSer . io_Length = Size;
if(!DoIO(ReadRequest))
return(Size);
}
}
}
return(0);
}
/* xpr_swrite(UBYTE *Buffer,LONG Size):
*
* Write a few bytes to the serial port.
*/
LONG __saveds __asm
xpr_swrite(register __a0 UBYTE *Buffer,register __d0 LONG Size)
{
if(WriteRequest)
{
WriteRequest -> IOSer . io_Command = CMD_WRITE;
WriteRequest -> IOSer . io_Data = Buffer;
WriteRequest -> IOSer . io_Length = Size;
return((LONG)DoIO(WriteRequest));
}
else
return(-1);
}
/* xpr_sflush():
*
* Release the contents of all serial buffers.
*/
LONG __saveds
xpr_sflush()
{
if(WriteRequest)
{
WriteRequest -> IOSer . io_Command = CMD_CLEAR;
return((LONG)DoIO(WriteRequest));
}
else
return(-1);
}
/* GetSeconds(UBYTE *String):
*
* Tries to turn a string of the format hh:mm:ss into
* an integer number.
*/
STATIC LONG __regargs
GetSeconds(UBYTE *String)
{
UBYTE Buffer[20];
LONG Seconds = 0;
memset(Buffer,0,20);
strcpy(Buffer,String);
Seconds += atol(&Buffer[6]);
Buffer[5] = 0;
Seconds += atol(&Buffer[3]) * 60;
Buffer[2] = 0;
Seconds += atol(&Buffer[0]) * 3600;
return(Seconds);
}
/* TruncateName(UBYTE *FileName):
*
* Truncates a file name to a maximum of 48 characters.
*/
STATIC UBYTE * __regargs
TruncateName(UBYTE *FileName)
{
WORD Len = strlen(FileName);
if(Len > 48)
{
WORD i;
for(i = Len - 48 ; i < Len ; i++)
{
if(i >= Len - 44 && FileName[i] == '/')
{
STATIC UBYTE NameBuffer[256];
strcpy(NameBuffer,".../");
strcat(NameBuffer,&FileName[i + 1]);
return(NameBuffer);
}
}
}
return(FileName);
}
/* CalculateBlocks(LONG Size,LONG BlockSize):
*
* Calculate the number of blocks a file will
* occupy if saved to a disk.
*/
STATIC LONG __regargs
CalculateBlocks(LONG Size,LONG BlockSize)
{
LONG Blocks = 1; /* One for the file header. */
BYTE HasExtension = FALSE, /* No extension block yet. */
Extension = 0; /* How many block pointers yet. */
/* Round to next block. */
Size = ((Size + BlockSize - 1) / BlockSize) * BlockSize;
while(Size)
{
/* Add another block. */
Blocks++;
/* Subtract another block. */
Size -= BlockSize;
/* Add another block pointer, if 72 have been
* added, add another extension block.
*/
if((Extension++) == 72)
{
/* If no extension block has been generated
* yet, we were running on the block pointers
* of the file header itself.
*/
if(!HasExtension)
HasExtension = TRUE;
else
Blocks++;
/* Reset extension block counter. */
Extension = 0;
}
}
return(Blocks);
}
/* xpr_update(struct XPR_UPDATE *UpdateInfo):
*
* Update the information displayed in the transfer window.
*/
LONG __saveds __asm
xpr_update(register __a0 struct XPR_UPDATE *UpdateInfo)
{
if(!TransferWindow)
{
BlockWindows();
LogAction(LocaleString(MSG_TERMXPR_LOGMSG_INITIATE_BINARY_DOWNLOAD_TXT));
if(!TransferPanel(LocaleString(MSG_TERMXPR_RECEIVE_FILES_TXT)))
{
ReleaseWindows();
return(0);
}
}
if(UpdateInfo)
{
BYTE NewByte = FALSE,
NewTime = FALSE;
if((UpdateInfo -> xpru_updatemask & XPRU_PROTOCOL) && UpdateInfo -> xpru_protocol)
{
GT_SetGadgetAttrs(TransferGadgetArray[4],TransferWindow,NULL,
GTTX_Text, UpdateInfo -> xpru_protocol,
TAG_DONE);
}
if((UpdateInfo -> xpru_updatemask & XPRU_MSG) && UpdateInfo -> xpru_msg)
{
GT_SetGadgetAttrs(TransferGadgetArray[5],TransferWindow,NULL,
GTTX_Text, UpdateInfo -> xpru_msg,
TAG_DONE);
}
if((UpdateInfo -> xpru_updatemask & XPRU_ERRORMSG) && UpdateInfo -> xpru_errormsg)
AddTransferInfo(UpdateInfo -> xpru_errormsg);
if((UpdateInfo -> xpru_updatemask & XPRU_FILENAME) && UpdateInfo -> xpru_filename)
{
if(Config . OverridePath && !Uploading)
{
if(!RealName[0])
{
if(!DownloadPath)
strcpy(RealName,&Config . BinaryDownloadPath[0]);
else
strcpy(RealName,DownloadPath);
if(!AddPart(RealName,FilePart(UpdateInfo -> xpru_filename),256))
strcpy(RealName,UpdateInfo -> xpru_filename);
}
TransferInfo(19, 0,"%-48.48s",TruncateName(RealName));
}
else
TransferInfo(19, 0,"%-48.48s",TruncateName(UpdateInfo -> xpru_filename));
}
if((UpdateInfo -> xpru_updatemask & XPRU_FILESIZE) && UpdateInfo -> xpru_filesize != -1)
{
if(CurrentFile -> DirLock && CurrentFile -> InfoData . id_NumBlocks && CurrentFile -> InfoData . id_BytesPerBlock)
TransferInfo(19, 1,ConvNumber10,UpdateInfo -> xpru_filesize);
else
TransferInfo(19, 1,ConvNumber,UpdateInfo -> xpru_filesize);
if(ByteMax = UpdateInfo -> xpru_filesize)
NewByte = TRUE;
}
if((UpdateInfo -> xpru_updatemask & XPRU_BYTES) && UpdateInfo -> xpru_bytes != -1)
{
TransferInfo(19, 4,ConvNumber,ByteVal = UpdateInfo -> xpru_bytes);
if(ByteMax)
NewByte = TRUE;
if(CurrentFile -> DirLock && !Uploading)
{
if(CurrentFile -> InfoData . id_NumBlocks && CurrentFile -> InfoData . id_BytesPerBlock)
{
if(ByteMax)
{
register LONG Blocks = CalculateBlocks(ByteMax,CurrentFile -> InfoData . id_BytesPerBlock),Space = CurrentFile -> InfoData . id_NumBlocks - CurrentFile -> InfoData . id_NumBlocksUsed;
TransferInfo(19, 2,LocaleString(MSG_TERMXPR_BYTES_FULL_TXT),Space * CurrentFile -> InfoData . id_BytesPerBlock,100 * (CurrentFile -> InfoData . id_NumBlocksUsed) / CurrentFile -> InfoData . id_NumBlocks,(Space < Blocks) ? LocaleString(MSG_TERMXPR_FILE_MAY_NOT_FIT_TXT) : "");
/* Tell the user that he might be
* running into trouble.
*/
if(!Alerted && (Space < Blocks))
{
Alerted = TRUE;
BumpWindow(TransferWindow);
Say(LocaleString(MSG_TERMXPR_SAY_FILE_MAY_NOT_FIT_TXT));
}
}
else
TransferInfo(19, 2,LocaleString(MSG_TERMXPR_BYTES_FULL_TXT),(CurrentFile -> InfoData . id_NumBlocks - CurrentFile -> InfoData . id_NumBlocksUsed) * CurrentFile -> InfoData . id_BytesPerBlock,100 * (CurrentFile -> InfoData . id_NumBlocksUsed) / CurrentFile -> InfoData . id_NumBlocks);
}
}
}
if((UpdateInfo -> xpru_updatemask & XPRU_BLOCKS) && UpdateInfo -> xpru_blocks != -1)
TransferInfo(19, 5,ConvNumber,UpdateInfo -> xpru_blocks);
if((UpdateInfo -> xpru_updatemask & XPRU_BLOCKSIZE) && UpdateInfo -> xpru_blocksize != -1)
TransferInfo(19, 6,ConvNumber,UpdateInfo -> xpru_blocksize);
if((UpdateInfo -> xpru_updatemask & XPRU_BLOCKCHECK) && UpdateInfo -> xpru_blockcheck)
TransferInfo(19, 7,"%-12.12s",UpdateInfo -> xpru_blockcheck);
if((UpdateInfo -> xpru_updatemask & XPRU_EXPECTTIME) && UpdateInfo -> xpru_expecttime)
{
TransferInfo(19, 9,"%-12.12s",UpdateInfo -> xpru_expecttime);
if(TimeMax = GetSeconds((UBYTE *)UpdateInfo -> xpru_expecttime))
NewTime = TRUE;
}
if((UpdateInfo -> xpru_updatemask & XPRU_ELAPSEDTIME) && UpdateInfo -> xpru_elapsedtime)
{
TransferInfo(19,10,"%-12.12s",UpdateInfo -> xpru_elapsedtime);
TimeVal = GetSeconds((UBYTE *)UpdateInfo -> xpru_elapsedtime);
if(TimeMax)
NewTime = TRUE;
}
if((UpdateInfo -> xpru_updatemask & XPRU_DATARATE) && UpdateInfo -> xpru_datarate != -1)
TransferInfo(54, 4,ConvNumber,UpdateInfo -> xpru_datarate);
if((UpdateInfo -> xpru_updatemask & XPRU_CHARDELAY) && UpdateInfo -> xpru_chardelay != -1)
TransferInfo(54, 5,ConvNumber,UpdateInfo -> xpru_chardelay);
if((UpdateInfo -> xpru_updatemask & XPRU_PACKETDELAY) && UpdateInfo -> xpru_packetdelay != -1)
TransferInfo(54, 6,ConvNumber,UpdateInfo -> xpru_packetdelay);
if((UpdateInfo -> xpru_updatemask & XPRU_PACKETTYPE) && UpdateInfo -> xpru_packettype != -1)
{
if(UpdateInfo -> xpru_packettype > 31 && UpdateInfo -> xpru_packettype < 256)
{
if(ValidTab[UpdateInfo -> xpru_packettype])
TransferInfo(54, 7,"`%lc'",UpdateInfo -> xpru_packettype);
else
TransferInfo(54, 7,ConvNumber,UpdateInfo -> xpru_packettype);
}
else
TransferInfo(54, 7,ConvNumber,UpdateInfo -> xpru_packettype);
}
if((UpdateInfo -> xpru_updatemask & XPRU_ERRORS) && UpdateInfo -> xpru_errors != -1)
TransferInfo(54, 9,ConvNumber,UpdateInfo -> xpru_errors);
if((UpdateInfo -> xpru_updatemask & XPRU_TIMEOUTS) && UpdateInfo -> xpru_timeouts != -1)
TransferInfo(54,10,ConvNumber,UpdateInfo -> xpru_timeouts);
if(TransferWindow)
{
if(NewByte)
{
ShowStats(TransferGadgetArray[2],ByteVal,ByteMax);
if(ByteMax)
ShowString(TransferGadgetArray[2],"%3ld%%",(100 * ByteVal) / ByteMax);
else
ShowString(TransferGadgetArray[2],"%3ld%%",0);
}
if(NewTime)
{
LONG TimeDif = (TimeMax - TimeVal) < 0 ? 0 : TimeMax - TimeVal;
ShowStats(TransferGadgetArray[3],TimeDif,TimeMax);
ShowString(TransferGadgetArray[3],"%2ld:%02ld:%02ld",TimeDif / 3600,(TimeDif / 60) % 60,TimeDif % 60);
}
}
}
return(1);
}
/* xpr_chkabort():
*
* Check if the user has aborted the transfer.
*/
LONG __saveds
xpr_chkabort()
{
LONG Result = 0;
if(TransferWindow)
{
struct IntuiMessage *Massage;
ULONG Class,Code;
struct Gadget *Gadget;
while(Massage = (struct IntuiMessage *)GT_GetIMsg(TransferWindow -> UserPort))
{
Class = Massage -> Class;
Code = Massage -> Code;
Gadget = (struct Gadget *)Massage -> IAddress;
GT_ReplyIMsg(Massage);
if(!Result)
{
if(Class == IDCMP_VANILLAKEY)
KeySelect(TransferGadgetArray,1,Code,TransferWindow,&Gadget,&Class,&Code);
if(Class == IDCMP_NEWSIZE)
{
if(!(TransferWindow -> Flags & WFLG_ZOOMED))
RefreshTransferWindow();
}
if(Class == IDCMP_CLOSEWINDOW)
{
LogAction(LocaleString(MSG_TERMXPR_LOGMSG_TRANSFER_ABORTED_TXT));
TransferAborted = TRUE;
Result = -1;
}
if(Class == IDCMP_GADGETUP)
{
switch(Gadget -> GadgetID)
{
case 0: LogAction(LocaleString(MSG_TERMXPR_LOGMSG_TRANSFER_ABORTED_TXT));
TransferAborted = TRUE;
Result = -1;
break;
case 1: LogAction(LocaleString(MSG_TERMXPR_LOGMSG_FILE_SKIPPED_TXT));
Result = 1;
break;
default:break;
}
}
}
}
}
return(Result);
}
/* The following subroutine creates the gadgets required by
* xpr_gets().
*/
struct Gadget *
CreateAllGetsGadgets(BYTE LoadGadget,UBYTE *String,UBYTE *Prompt,LONG *WindowWidth,struct Gadget **GadgetArray,struct Gadget **GadgetList,APTR VisualInfo,UWORD TopEdge,struct Screen *Screen)
{
struct Gadget *Gadget;
struct NewGadget NewGadget;
memset(&NewGadget,0,sizeof(struct NewGadget));
if(Gadget = CreateContext(GadgetList))
{
WORD Width = strlen(Prompt),Counter = 0;
if(Width < 40)
Width = 40;
NewGadget . ng_Width = Width * 8 + 6;
NewGadget . ng_Height = 14;
NewGadget . ng_GadgetText = Prompt;
NewGadget . ng_TextAttr = &DefaultFont;
NewGadget . ng_VisualInfo = VisualInfo;
NewGadget . ng_GadgetID = Counter;
NewGadget . ng_Flags = PLACETEXT_ABOVE;
NewGadget . ng_LeftEdge = 10;
NewGadget . ng_TopEdge = 1 + TopEdge + 8 + 8;
GadgetArray[Counter++] = Gadget = CreateGadget(STRING_KIND,Gadget,&NewGadget,
GTST_MaxChars, 255,
GTST_String, String,
GTST_EditHook, &CommandHook,
GA_Immediate, TRUE,
TAG_DONE);
if(Gadget)
*WindowWidth = Gadget -> Width + 32;
else
*WindowWidth = 200;
NewGadget . ng_Width = 88;
NewGadget . ng_Height = 12;
NewGadget . ng_GadgetText = LocaleString(MSG_TERMXPR_OKAY_GAD);
NewGadget . ng_GadgetID = Counter;
NewGadget . ng_Flags = 0;
NewGadget . ng_TopEdge = NewGadget . ng_TopEdge + NewGadget . ng_Height + 3;
GadgetArray[Counter++] = Gadget = CreateGadget(BUTTON_KIND,Gadget,&NewGadget,
GT_Underscore, '_',
TAG_DONE);
if(LoadGadget)
{
NewGadget . ng_Width = 88;
NewGadget . ng_GadgetText = LocaleString(MSG_TERMXPR_LOAD_FILE_GAD);
NewGadget . ng_GadgetID = Counter;
NewGadget . ng_LeftEdge = (*WindowWidth - NewGadget . ng_Width) >> 1;
GadgetArray[Counter++] = Gadget = CreateGadget(BUTTON_KIND,Gadget,&NewGadget,
GT_Underscore, '_',
TAG_DONE);
}
else
Counter++;
NewGadget . ng_Width = 88;
NewGadget . ng_GadgetText = LocaleString(MSG_GLOBAL_CANCEL_GAD);
NewGadget . ng_GadgetID = Counter;
NewGadget . ng_LeftEdge = GadgetArray[0] -> LeftEdge + GadgetArray[0] -> Width + 6 - NewGadget . ng_Width;
GadgetArray[Counter] = Gadget = CreateGadget(BUTTON_KIND,Gadget,&NewGadget,
GT_Underscore, '_',
TAG_DONE);
}
return(Gadget);
}
/* xpr_gets(UBYTE *Prompt,UBYTE *Buffer):
*
* Prompt the user for string input.
*/
LONG __saveds __asm
xpr_gets(register __a0 UBYTE *Prompt,register __a1 UBYTE *Buffer)
{
struct Gadget *GadgetList = NULL;
struct Gadget *GadgetArray[4];
struct Window *PanelWindow;
LONG Width,Success = FALSE;
if(!Prompt)
Prompt = LocaleString(MSG_TERMXPR_INPUT_REQUIRED_TXT);
if(CreateAllGetsGadgets(FALSE,Buffer,Prompt,&Width,&GadgetArray[0],&GadgetList,VisualInfo,Screen -> WBorTop + Screen -> Font -> ta_YSize + 1,Screen))
{
if(PanelWindow = OpenWindowTags(NULL,
WA_Width, Width,
WA_Height, 58,
WA_Left, (Screen -> Width - Width) >> 1,
WA_Top, (Screen -> Height - 56) >> 1,
WA_Activate, TRUE,
WA_DragBar, TRUE,
WA_DepthGadget, TRUE,
WA_CloseGadget, TRUE,
WA_RMBTrap, TRUE,
WA_CustomScreen,Screen,
WA_IDCMP, IDCMP_GADGETDOWN | IDCMP_ACTIVEWINDOW | IDCMP_CLOSEWINDOW | IDCMP_VANILLAKEY | BUTTONIDCMP | STRINGIDCMP,
WA_Title, LocaleString(MSG_GLOBAL_ENTER_TEXT_TXT),
TAG_DONE))
{
struct IntuiMessage *Massage;
ULONG Class,Code;
struct Gadget *Gadget;
BYTE Terminated = FALSE;
PushWindow(PanelWindow);
AddGList(PanelWindow,GadgetList,(UWORD)-1,(UWORD)-1,NULL);
RefreshGList(GadgetList,PanelWindow,NULL,(UWORD)-1);
GT_RefreshWindow(PanelWindow,NULL);
ActiveGadget = NULL;
while(!Terminated)
{
WaitPort(PanelWindow -> UserPort);
while(!Terminated && (Massage = (struct IntuiMessage *)GT_GetIMsg(PanelWindow -> UserPort)))
{
Class = Massage -> Class;
Code = Massage -> Code;
Gadget = (struct Gadget *)Massage -> IAddress;
GT_ReplyIMsg(Massage);
if(Class == IDCMP_VANILLAKEY)
KeySelect(GadgetArray,3,Code,PanelWindow,&Gadget,&Class,&Code);
if(Class == IDCMP_GADGETDOWN)
{
if((Gadget -> GadgetType & GTYP_GTYPEMASK) == GTYP_STRGADGET)
ActiveGadget = Gadget;
}
if(Class == IDCMP_GADGETDOWN)
{
if((Gadget -> GadgetType & GTYP_GTYPEMASK) == GTYP_STRGADGET)
ActiveGadget = Gadget;
}
if(Class == IDCMP_ACTIVEWINDOW && ActiveGadget)
ActivateGadget(ActiveGadget,PanelWindow,NULL);
if(Class == IDCMP_CLOSEWINDOW)
Terminated = TRUE;
if(Class == IDCMP_GADGETUP)
{
switch(Gadget -> GadgetID)
{
case 0: if(Code != '\t')
{
strcpy(Buffer,GT_STRING(GadgetArray[0]));
Success = TRUE;
Terminated = TRUE;
break;
}
case 1: strcpy(Buffer,GT_STRING(GadgetArray[0]));
Success = TRUE;
Terminated = TRUE;
break;
case 3: Terminated = TRUE;
break;
}
}
}
}
ActiveGadget = NULL;
RemoveGList(PanelWindow,GadgetList,(UWORD)-1);
PopWindow();
CloseWindow(PanelWindow);
}
FreeGadgets(GadgetList);
}
return(Success);
}
/* xpr_setserial(LONG Status):
*
* Set/read the serial status (parameters).
*/
LONG __saveds __asm
xpr_setserial(register __d0 LONG Status)
{
if(WriteRequest)
{
STATIC LONG XprBauds[12] =
{
110,
300,
1200,
2400,
4800,
9600,
19200,
31250,
38400,
57600,
76800,
115200
};
LONG Return,i;
WriteRequest -> IOSer . io_Command = SDCMD_QUERY;
DoIO(WriteRequest);
Return = WriteRequest -> io_SerFlags & 0xFF;
if(WriteRequest -> io_ExtFlags & SEXTF_MSPON)
Return |= ST_PARTYMARKON;
if(WriteRequest -> io_ExtFlags & SEXTF_MARK)
Return |= ST_PARTYMARK;
if(WriteRequest -> io_StopBits == 2)
Return |= ST_2BITS;
if(WriteRequest -> io_ReadLen == 7)
Return |= ST_READ7;
if(WriteRequest -> io_WriteLen == 7)
Return |= ST_WRITE7;
for(i = 0 ; i < 12 ; i++)
{
if(WriteRequest -> io_Baud <= XprBauds[i])
{
Return |= (i << 16);
break;
}
}
if(Status != -1)
{
WriteRequest -> IOSer . io_Command = SDCMD_SETPARAMS;
WriteRequest -> io_SerFlags = Status & 0xFF;
WriteRequest -> io_ExtFlags = 0;
if(Status & ST_PARTYMARKON)
WriteRequest -> io_ExtFlags |= SEXTF_MSPON;
if(Status & ST_PARTYMARK)
WriteRequest -> io_ExtFlags |= SEXTF_MARK;
if(Status & ST_2BITS)
WriteRequest -> io_StopBits = 2;
else
WriteRequest -> io_StopBits = 1;
if(Status & ST_READ7)
WriteRequest -> io_ReadLen = 7;
else
WriteRequest -> io_ReadLen = 8;
if(Status & ST_WRITE7)
WriteRequest -> io_WriteLen = 7;
else
WriteRequest -> io_WriteLen = 8;
DoIO(WriteRequest);
ReadRequest -> io_SerFlags = WriteRequest -> io_SerFlags;
ReadRequest -> io_ExtFlags = WriteRequest -> io_ExtFlags;
ReadRequest -> io_StopBits = WriteRequest -> io_StopBits;
ReadRequest -> io_ReadLen = WriteRequest -> io_ReadLen;
ReadRequest -> io_WriteLen = WriteRequest -> io_WriteLen;
}
return(Return);
}
else
return(-1);
}
/* xpr_ffirst(UBYTE *Buffer,UBYTE *Pattern):
*
* Batch file upload: find the first matching file and return
* its name.
*/
LONG __saveds __asm
xpr_ffirst(register __a0 UBYTE *Buffer,register __a1 UBYTE *Pattern)
{
if(MultipleFiles)
{
FileCount = 0;
strcpy(Buffer,FileArg[FileCount++] . wa_Name);
return(1);
}
else
{
FileMatch = TRUE;
if(!MatchFirst(Pattern,FileAnchor))
{
if(FileAnchor -> ap_Info . fib_DirEntryType < 0)
{
strcpy(Buffer,FileAnchor -> ap_Info . fib_FileName);
return(1);
}
else
{
while(!MatchNext(FileAnchor))
{
if(FileAnchor -> ap_Info . fib_DirEntryType < 0)
{
strcpy(Buffer,FileAnchor -> ap_Info . fib_FileName);
return(1);
}
}
}
}
}
return(0);
}
/* xpr_fnext(LONG OldState,UBYTE *Buffer,UBYTE *Pattern):
*
* Batch file upload: find the next matching file
* - if any - and return its name.
*/
LONG __saveds __asm
xpr_fnext(register __d0 LONG OldState,register __a0 UBYTE *Buffer,register __a1 UBYTE *Pattern)
{
if(MultipleFiles)
{
if(FileCount < FileCountMax)
{
strcpy(Buffer,FileArg[FileCount++] . wa_Name);
return(1);
}
}
else
{
FileMatch = TRUE;
while(!MatchNext(FileAnchor))
{
if(FileAnchor -> ap_Info . fib_DirEntryType < 0)
{
strcpy(Buffer,FileAnchor -> ap_Info . fib_FileName);
return(1);
}
}
}
return(0);
}
/* xpr_finfo(UBYTE *FileName,LONG InfoType):
*
* Return information on a given file.
*/
LONG __saveds __asm
xpr_finfo(register __a0 UBYTE *FileName,register __d0 LONG InfoType)
{
BPTR FileLock;
switch(InfoType)
{
case 1: if(Config . OverridePath && !Uploading)
{
if(!DownloadPath)
{
if(!Config . BinaryDownloadPath[0])
{
if(!GetCurrentDirName(RealName,256))
RealName[0] = 0;
}
else
strcpy(RealName,Config . BinaryDownloadPath);
}
else
{
if(!DownloadPath[0])
{
if(!GetCurrentDirName(RealName,256))
RealName[0] = 0;
}
else
strcpy(RealName,DownloadPath);
}
if(AddPart(RealName,FilePart(FileName),256))
FileName = RealName;
}
if(FileLock = Lock(FileName,ACCESS_READ))
{
struct FileInfoBlock __aligned FileInfo;
register LONG Size;
if(Examine(FileLock,&FileInfo))
Size = FileInfo . fib_Size;
else
Size = 0;
UnLock(FileLock);
return(Size);
}
break;
case 2: return(BinaryTransfer ? 1 : 2);
}
return(0);
}
/* The following routines are to support the xpr_options function. */
STATIC BYTE __regargs
GetOptionMode(struct xpr_option *Option)
{
if(Option)
{
if(!Stricmp(Option -> xpro_value,"OFF"))
return(FALSE);
if(!Stricmp(Option -> xpro_value,"FALSE"))
return(FALSE);
if(!Stricmp(Option -> xpro_value,"F"))
return(FALSE);
if(!Stricmp(Option -> xpro_value,"NO"))
return(FALSE);
if(!Stricmp(Option -> xpro_value,"N"))
return(FALSE);
if(!Stricmp(Option -> xpro_value,"ON"))
return(TRUE);
if(!Stricmp(Option -> xpro_value,"TRUE"))
return(TRUE);
if(!Stricmp(Option -> xpro_value,"T"))
return(TRUE);
if(!Stricmp(Option -> xpro_value,"YES"))
return(TRUE);
if(!Stricmp(Option -> xpro_value,"Y"))
return(TRUE);
}
return(FALSE);
}
STATIC struct Gadget *
CreateAllOptionGadgets(LONG *Count,LONG *Width,LONG *Height,LONG NumOpts,struct xpr_option *Opts[],struct Gadget *GadgetArray[],struct Gadget **GadgetList,APTR VisualInfo,UWORD TopEdge)
{
struct Gadget *Gadget;
struct NewGadget NewGadget;
LONG i,MaxLength = 0,MaxLength1 = 0,AddTop = 0,Len,LeftPlus = 0,MaxRight = 0,MaxWidth = 0,NumOptsSmall,Tmp;
memset(&NewGadget,0,sizeof(struct NewGadget));
*Count = 0;
if(Gadget = CreateContext(GadgetList))
{
NewGadget . ng_TopEdge = TopEdge + 1;
NewGadget . ng_Height = 12;
NewGadget . ng_Width = 208;
NewGadget . ng_TextAttr = &DefaultFont;
NewGadget . ng_VisualInfo = VisualInfo;
NewGadget . ng_Flags = NG_HIGHLABEL;
/* Precalculate gadget left edge offset. */
if((NumOptsSmall = NumOpts) > OPTION_WRAP)
NumOptsSmall = OPTION_WRAP;
for(i = 0 ; i < NumOptsSmall ; i++)
{
if(Opts[i])
{
switch(Opts[i] -> xpro_type)
{
case XPRO_BOOLEAN:
case XPRO_LONG:
case XPRO_STRING:
case XPRO_COMMPAR:
if((Len = strlen(Opts[i] -> xpro_description)) > MaxLength)
MaxLength = Len;
break;
case XPRO_COMMAND:
if(MaxLength < 25)
MaxLength = 25;
break;
default:
break;
}
}
}
if(MaxLength < 16)
MaxLength = 16;
if(MaxLength < 25)
MaxLength = (25 - MaxLength) * 8;
else
MaxLength = 0;
for(i = OPTION_WRAP ; i < NumOpts ; i++)
{
if(Opts[i])
{
switch(Opts[i] -> xpro_type)
{
case XPRO_BOOLEAN:
case XPRO_LONG:
case XPRO_STRING:
case XPRO_COMMPAR:
if((Len = strlen(Opts[i] -> xpro_description)) > MaxLength1)
MaxLength1 = Len;
break;
case XPRO_COMMAND:
if(MaxLength1 < 25)
MaxLength1 = 25;
break;
default:
break;
}
}
}
if(MaxLength1 < 16)
MaxLength1 = 16;
if(MaxLength1 < 25)
MaxLength1 = (25 - MaxLength1) * 8;
else
MaxLength1 = 0;
*Height = 0;
for(i = 0 ; i < NumOpts ; i++)
{
if(!Opts[i])
continue;
switch(Opts[i] -> xpro_type)
{
case XPRO_BOOLEAN:
NewGadget . ng_GadgetText = Opts[i] -> xpro_description;
NewGadget . ng_GadgetID = i;
NewGadget . ng_Width = 26;
NewGadget . ng_Height = 11;
NewGadget . ng_LeftEdge = 218 - MaxLength + LeftPlus;
NewGadget . ng_TopEdge = NewGadget . ng_TopEdge + AddTop;
GadgetArray[i] = Gadget = CreateGadget(CHECKBOX_KIND,Gadget,&NewGadget,
GTCB_Checked, GetOptionMode(Opts[i]),
TAG_DONE);
break;
case XPRO_LONG:
NewGadget . ng_GadgetText = Opts[i] -> xpro_description;
NewGadget . ng_GadgetID = i;
NewGadget . ng_LeftEdge = 218 - MaxLength + LeftPlus;
NewGadget . ng_TopEdge = NewGadget . ng_TopEdge + AddTop;
NewGadget . ng_Height = 14;
GadgetArray[i] = Gadget = CreateGadget(INTEGER_KIND,Gadget,&NewGadget,
GTIN_Number, atol(Opts[i] -> xpro_value),
GTST_EditHook, &CommandHook,
GA_Immediate, TRUE,
TAG_DONE);
break;
case XPRO_STRING:
case XPRO_COMMPAR:
NewGadget . ng_GadgetText = Opts[i] -> xpro_description;
NewGadget . ng_GadgetID = i;
NewGadget . ng_LeftEdge = 218 - MaxLength + LeftPlus;
NewGadget . ng_TopEdge = NewGadget . ng_TopEdge + AddTop;
NewGadget . ng_Height = 14;
GadgetArray[i] = Gadget = CreateGadget(STRING_KIND,Gadget,&NewGadget,
GTST_String, Opts[i] -> xpro_value,
GTST_MaxChars, Opts[i] -> xpro_length - 1,
GTST_EditHook, &CommandHook,
GA_Immediate, TRUE,
TAG_DONE);
break;
case XPRO_HEADER:
NewGadget . ng_GadgetText = "";
NewGadget . ng_GadgetID = i;
NewGadget . ng_LeftEdge = 10 + LeftPlus;
NewGadget . ng_TopEdge = NewGadget . ng_TopEdge + AddTop;
NewGadget . ng_Flags = 0;
NewGadget . ng_Height = 8;
NewGadget . ng_Width = 8 * strlen(Opts[i] -> xpro_description);
GadgetArray[i] = Gadget = CreateGadget(TEXT_KIND,Gadget,&NewGadget,
GTTX_Text, Opts[i] -> xpro_description,
TAG_DONE);
break;
case XPRO_COMMAND:
NewGadget . ng_GadgetText = Opts[i] -> xpro_description;
NewGadget . ng_GadgetID = i;
NewGadget . ng_LeftEdge = 10 + LeftPlus;
NewGadget . ng_TopEdge = NewGadget . ng_TopEdge + 13;
GadgetArray[i] = Gadget = CreateGadget(BUTTON_KIND,Gadget,&NewGadget,
TAG_DONE);
break;
default:break;
}
if(MaxWidth < (Tmp = NewGadget . ng_LeftEdge + NewGadget .ng_Width + 10))
MaxWidth = Tmp;
AddTop = NewGadget . ng_Height + 1;
if(i < OPTION_WRAP)
{
if(NewGadget . ng_LeftEdge + NewGadget . ng_Width > MaxRight)
MaxRight = NewGadget . ng_LeftEdge + NewGadget . ng_Width;
if(i == OPTION_WRAP - 1)
{
LeftPlus = MaxRight;
*Height = NewGadget . ng_TopEdge + NewGadget . ng_Height + 3;
MaxLength = MaxLength1;
NewGadget . ng_TopEdge = TopEdge + 1;
AddTop = 0;
}
}
if(i < NumOpts - 1)
{
NewGadget . ng_Height = 12;
NewGadget . ng_Width = 208;
NewGadget . ng_Flags = NG_HIGHLABEL;
}
}
if(Gadget)
{
if(NewGadget . ng_TopEdge + NewGadget . ng_Height + 3 > *Height)
*Height = NewGadget . ng_TopEdge + NewGadget . ng_Height + 3;
*Count = i;
*Width = MaxWidth;
}
}
return(Gadget);
}
/* xpr_options(LONG NumOpts,struct xpr_option **Opts):
*
* Provide a more polished user interface to set the
* transfer protocol options.
*/
ULONG __saveds __asm
xpr_options(register __d0 LONG NumOpts,register __a0 struct xpr_option **Opts)
{
struct Gadget *GadgetList = NULL;
struct Gadget *GadgetArray[34];
struct Window *PanelWindow;
LONG Width,Height,i,Count;
ULONG Flags = 0;
if(CreateAllOptionGadgets(&Count,&Width,&Height,NumOpts,Opts,&GadgetArray[0],&GadgetList,VisualInfo,Screen -> WBorTop + Screen -> Font -> ta_YSize + 1))
{
if(PanelWindow = OpenWindowTags(NULL,
WA_Width, Width,
WA_Height, Height,
WA_Left, (Screen -> Width - Width) >> 1,
WA_Top, (Screen -> Height - Height) >> 1,
WA_Activate, TRUE,
WA_DragBar, TRUE,
WA_DepthGadget, TRUE,
WA_CloseGadget, TRUE,
WA_RMBTrap, TRUE,
WA_CustomScreen,Screen,
WA_IDCMP, IDCMP_GADGETDOWN | IDCMP_ACTIVEWINDOW | IDCMP_CLOSEWINDOW | IDCMP_VANILLAKEY | CHECKBOXIDCMP | STRINGIDCMP | INTEGERIDCMP | BUTTONIDCMP,
WA_Title, OptionTitle ? OptionTitle : LocaleString(MSG_TERMXPR_TRANSFER_OPTIONS_TXT),
TAG_DONE))
{
struct IntuiMessage *Massage;
ULONG Class,Code;
struct Gadget *Gadget;
BYTE Terminated = FALSE;
PushWindow(PanelWindow);
AddGList(PanelWindow,GadgetList,(UWORD)-1,(UWORD)-1,NULL);
RefreshGList(GadgetList,PanelWindow,NULL,(UWORD)-1);
GT_RefreshWindow(PanelWindow,NULL);
ActiveGadget = NULL;
while(!Terminated)
{
WaitPort(PanelWindow -> UserPort);
while(!Terminated && (Massage = (struct IntuiMessage *)GT_GetIMsg(PanelWindow -> UserPort)))
{
Class = Massage -> Class;
Code = Massage -> Code;
Gadget = (struct Gadget *)Massage -> IAddress;
GT_ReplyIMsg(Massage);
if(Class == IDCMP_VANILLAKEY)
KeySelect(GadgetArray,Count,Code,PanelWindow,&Gadget,&Class,&Code);
if(Class == IDCMP_GADGETDOWN)
{
if((Gadget -> GadgetType & GTYP_GTYPEMASK) == GTYP_STRGADGET)
ActiveGadget = Gadget;
}
if(Class == IDCMP_ACTIVEWINDOW && ActiveGadget)
ActivateGadget(ActiveGadget,PanelWindow,NULL);
if(Class == IDCMP_CLOSEWINDOW)
Terminated = TRUE;
if(Class == IDCMP_GADGETUP)
{
if(Gadget -> GadgetID < NumOpts)
{
if(Opts[Gadget -> GadgetID] -> xpro_type == XPRO_COMMAND)
{
Flags |= (1 << Gadget -> GadgetID);
Terminated = TRUE;
}
}
}
if(Terminated)
{
if(!OptionTitle)
NewOptions = FALSE;
for(i = 0 ; i < NumOpts ; i++)
{
switch(Opts[i] -> xpro_type)
{
case XPRO_BOOLEAN: if(GT_CHECKED(GadgetArray[i]) != GetOptionMode(Opts[i]))
{
Flags |= (1 << i);
if(GT_CHECKED(GadgetArray[i]))
strcpy(Opts[i] -> xpro_value,"yes");
else
strcpy(Opts[i] -> xpro_value,"no");
if(!OptionTitle)
NewOptions = TRUE;
}
break;
case XPRO_COMMPAR:
case XPRO_LONG:
case XPRO_STRING: if(strcmp(Opts[i] -> xpro_value,GT_STRING(GadgetArray[i])))
{
Flags |= (1 << i);
strcpy(Opts[i] -> xpro_value,GT_STRING(GadgetArray[i]));
if(!OptionTitle)
NewOptions = TRUE;
}
break;
default: break;
}
}
}
}
}
ActiveGadget = NULL;
RemoveGList(PanelWindow,GadgetList,(UWORD)-1);
PopWindow();
CloseWindow(PanelWindow);
}
}
FreeGadgets(GadgetList);
return(Flags);
}
/* xpr_unlink(UBYTE *FileName):
*
* Remove (delete) a given file.
*/
LONG __saveds __asm
xpr_unlink(register __a0 UBYTE *FileName)
{
LONG Success = DeleteFile(FileName) ? 0 : -1;
if(Success)
LogAction(LocaleString(MSG_TERMXPR_LOGMSG_DELETE_FILE_TXT),FileName);
return(Success);
}
/* xpr_squery():
*
* Check how many characters are present in the serial buffer.
*/
LONG __saveds
xpr_squery()
{
if(WriteRequest)
{
WriteRequest -> IOSer . io_Command = SDCMD_QUERY;
if(!DoIO(WriteRequest))
return((LONG)WriteRequest -> IOSer . io_Actual);
}
return(-1);
}
/* xpr_getptr(LONG InfoType):
*
* Return a pointer to the term custom screen.
*/
LONG __saveds __asm
xpr_getptr(register __d0 LONG InfoType)
{
if(InfoType == 1)
return((LONG)Screen);
else
return(-1);
}
/* xpr_stealopts(UBYTE *Prompt,UBYTE *Buffer):
*
* Steal the contents of the options buffer (replacement
* for xpr_gets).
*/
LONG __saveds __asm
xpr_stealopts(register __a0 UBYTE *Prompt,register __a1 UBYTE *Buffer)
{
if(Buffer)
strcpy(ProtocolOptsBuffer,Buffer);
return(1);
}
/* ProtocolSetup():
*
* Set up the library and options for the external protocol.
*/
BYTE
ProtocolSetup()
{
UBYTE NameBuffer[40],i;
/* Close the old library if still open. */
if(XProtocolBase)
{
XProtocolCleanup(XprIO);
CloseLibrary(XProtocolBase);
}
/* Clear the XPR interface buffer. */
memset(XprIO,0,sizeof(struct XPR_IO));
/* Copy the name of the library. */
strcpy(NameBuffer,FilePart(LastXprLibrary));
/* Extract the name itself (strip the `.library'). */
for(i = strlen(NameBuffer) - 1 ; i >= 0 ; i--)
{
if(NameBuffer[i] == '.')
{
NameBuffer[i] = 0;
break;
}
}
/* Check if the transfer protocol is a sort of ZModem. */
UsesZModem = FALSE;
for(i = 0 ; i <= strlen(NameBuffer) - 6 ; i++)
{
if(!Stricmp(&NameBuffer[i],"zmodem"))
UsesZModem = TRUE;
}
/* Obtain the protocol default settings. */
if(!GetEnvDOS(NameBuffer,ProtocolOptsBuffer))
ProtocolOptsBuffer[0] = 0;
/* Initialize the interface structure. */
XprIO -> xpr_filename = ProtocolOptsBuffer;
XprIO -> xpr_fopen = (APTR)xpr_fopen;
XprIO -> xpr_fclose = (APTR)xpr_fclose;
XprIO -> xpr_fread = (APTR)xpr_fread;
XprIO -> xpr_fwrite = (APTR)xpr_fwrite;
XprIO -> xpr_sread = (APTR)xpr_sread;
XprIO -> xpr_swrite = (APTR)xpr_swrite;
XprIO -> xpr_sflush = (APTR)xpr_sflush;
XprIO -> xpr_update = (APTR)xpr_update;
XprIO -> xpr_chkabort = (APTR)xpr_chkabort;
XprIO -> xpr_gets = (APTR)xpr_gets;
XprIO -> xpr_setserial = (APTR)xpr_setserial;
XprIO -> xpr_ffirst = (APTR)xpr_ffirst;
XprIO -> xpr_fnext = (APTR)xpr_fnext;
XprIO -> xpr_finfo = (APTR)xpr_finfo;
XprIO -> xpr_fseek = (APTR)xpr_fseek;
XprIO -> xpr_extension = 4;
XprIO -> xpr_options = (APTR)xpr_options;
XprIO -> xpr_unlink = (APTR)xpr_unlink;
XprIO -> xpr_squery = (APTR)xpr_squery;
XprIO -> xpr_getptr = (APTR)xpr_getptr;
/* Try to open the library. */
if(XProtocolBase = (struct Library *)OpenLibrary(LastXprLibrary,0))
{
/* Set up the library. */
TransferBits = XProtocolSetup(XprIO);
/* Successful initialization? */
if(!(TransferBits & XPRS_SUCCESS))
{
MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FAILED_TO_SET_UP_PROTOCOL_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),LastXprLibrary);
CloseLibrary(XProtocolBase);
XProtocolBase = NULL;
LastXprLibrary[0] = 0;
TransferBits = 0;
return(FALSE);
}
if(TransferBits & XPRS_HOSTNOWAIT)
{
if(!HostReadBuffer)
HostReadBuffer = AllocVec(Config . SerBuffSize,MEMF_ANY);
}
else
{
if(HostReadBuffer)
{
FreeVec(HostReadBuffer);
HostReadBuffer = NULL;
}
}
}
else
MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FAILED_TO_OPEN_PROTOCOL_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),LastXprLibrary);
return(TRUE);
}
/* SaveProtocolOpts():
*
* Save the current protocol settings to an environment variable.
*/
VOID
SaveProtocolOpts()
{
/* It's time to save the altered options. */
if(NewOptions && XProtocolBase)
{
UBYTE NameBuffer[40],i;
/* Strip the `.library' part. */
strcpy(NameBuffer,FilePart(LastXprLibrary));
for(i = strlen(NameBuffer) - 1 ; i >= 0 ; i--)
{
if(NameBuffer[i] == '.')
{
NameBuffer[i] = 0;
break;
}
}
/* Cause the xpr.library to prompt for
* input. We expect the library to fill
* the prompt string with the default
* settings. The resulting string is
* intercepted by xpr_stealopts, saved
* to an environment variable and will
* serve as a reinitialization string
* later.
*/
XprIO -> xpr_filename = NULL;
XprIO -> xpr_gets = (APTR)xpr_stealopts;
XprIO -> xpr_extension = 4;
XprIO -> xpr_options = (APTR)NULL;
XProtocolSetup(XprIO);
/* Save the options in case anything goes
* wrong.
*/
NewOptions = FALSE;
SetEnvDOS(NameBuffer,ProtocolOptsBuffer);
/* Reinitialize the library. */
XprIO -> xpr_filename = ProtocolOptsBuffer;
XprIO -> xpr_gets = (APTR)xpr_gets;
XprIO -> xpr_extension = 4;
XprIO -> xpr_options = (APTR)xpr_options;
XProtocolSetup(XprIO);
}
}
/* SelectProtocol(UBYTE *Name,struct Window *ParentWindow):
*
* Select a different transfer protocol library using
* the asl.library file requester.
*/
BYTE
SelectProtocol(UBYTE *Name,struct Window *ParentWindow)
{
struct FileRequester *AslFileRequest;
UBYTE *File;
BYTE UseNewLibrary = FALSE;
File = Name;
if(FilePart(File) == File)
strcpy(SharedBuffer,"Libs:");
else
{
UBYTE *Temp;
strcpy(SharedBuffer,File);
Temp = PathPart(SharedBuffer);
Temp[0] = 0;
File = FilePart(File);
}
if(AslFileRequest = (struct FileRequester *)AllocAslRequestTags(ASL_FileRequest,
ASL_Window, ParentWindow,
ASL_File, File,
ASL_Dir, SharedBuffer,
ASL_Hail, LocaleString(MSG_TERMXPR_SELECT_TRANSFER_PROTOCOL_TXT),
ASL_FuncFlags, FILF_NEWIDCMP,
ASL_Pattern, "xpr#?.library",
ASL_OKText, LocaleString(MSG_GLOBAL_SELECT_TXT),
TAG_END))
{
if(AslRequestTags(AslFileRequest,TAG_DONE))
{
if(AslFileRequest -> rf_File[0])
{
if(Stricmp("Libs:",AslFileRequest -> rf_Dir))
{
strcpy(SharedBuffer,AslFileRequest -> rf_Dir);
if(!AddPart(SharedBuffer,AslFileRequest -> rf_File,256))
strcpy(SharedBuffer,AslFileRequest -> rf_File);
}
else
strcpy(SharedBuffer,AslFileRequest -> rf_File);
if(SharedBuffer[0] && Stricmp(SharedBuffer,Name))
{
strcpy(LastXprLibrary,SharedBuffer);
UseNewLibrary = TRUE;
}
}
}
FreeAslRequest(AslFileRequest);
}
return(UseNewLibrary);
}